import { _decorator, Component, Label, log, Node, Prefab, instantiate, Vec3, director, Scene, Director, game, SpriteAtlas, resources, Sprite } from 'cc';
import { pushBoxTs } from './pushBoxTs';
import { GlobalAttribute } from './SingletonPattern/GlobalAttribute';

const { ccclass, property } = _decorator;

@ccclass('easyrandomBox')
export class easyrandomBox extends Component {
    Global: GlobalAttribute;

    @property(Prefab)
    boxPrefab: Prefab = null; //预制体资源

    @property(SpriteAtlas)
    atlas: SpriteAtlas = null; // 图集资源

    @property(Node)
    stop: Node;

    @property(Node)
    checkpoint: Node;

    labelArr = [];
    blockNumber = 10;
    blockStartPos = -270;
    blockNumber14;
    initarr = [];
    row2;
    obj;
    newarr = [];
    Direction = null;
    el;
    protected onLoad(): void {
        this.Global = GlobalAttribute.getInstance();
        //遍历所有方块的总数 创建一个数组
        for (let i = 0; i < 25; i++) {
            let iconName = 'icon_' + (i + 1); // 确保图集中的图标命名为 icon_1, icon_2, ..., icon_25
            this.labelArr.push(iconName);
            this.labelArr.push(iconName);
            this.labelArr.push(iconName);
            this.labelArr.push(iconName);
        };
        this.labelArr.sort(() => Math.random() - 0.5);

        this.initializeBlocks();


    }
    initializeBlocks() {
        if (this.boxPrefab) {
            const spacing = 60; // 定义常量用于节点间距
            const totalNodes = this.blockNumber * this.blockNumber;
            const positions = new Array(totalNodes); // 用于存储所有节点的位置
            this.initarr = []; // 初始化二维数组
            let index;


            // 创建所有节点并设置它们的位置
            for (let i = 0; i < totalNodes; i++) {
                let rowx = Math.floor(i / this.blockNumber);
                let coly = i % this.blockNumber;
                positions[i] = this.calculatePosition(rowx, coly, spacing);
                let newNode = instantiate(this.boxPrefab);

                // 计算行和列
                let row = Math.floor(i / this.blockNumber);
                if (!this.initarr[row]) {
                    this.initarr[row] = [];
                }
                if (row !== this.row2) {
                    index = 0;
                    this.row2 = row;
                }
                // 创建包含位置信息和节点的对象
                this.obj = {
                    position: positions[i],
                    node: newNode,
                    texture: `${this.labelArr[i]}`,
                    x: row,
                    y: index
                };

                // 将实例化的节点添加到当前场景中
                this.node.addChild(this.obj.node);
                this.obj.node.setPosition(this.obj.position);

                this.setSprite(this.obj.texture)


                // 将对象添加到二维数组中
                this.initarr[row].push(this.obj);

                //将对象的索引也保存到对象中
                let pushboxTs = this.obj.node.getComponent(pushBoxTs);
                pushboxTs.initarrpos.x = row;
                pushboxTs.initarrpos.y = index;
                index++;
            }
        }
    }

    setSprite(e) {
        // 设置节点的纹理
        let spriteComponent = this.obj.node.getComponent(Sprite); // 修改变量名，避免重复声明
        spriteComponent.spriteFrame = this.atlas.getSpriteFrame(e);
    }

    // 计算节点位置的辅助函数
    private calculatePosition(row: number, col: number, spacing: number): Vec3 {
        let posx = this.blockStartPos + row * spacing;
        let posy = this.blockStartPos + col * spacing;
        return new Vec3(posx, posy, 0);
    }


    duibi() {

        let bool = false;
        let clearNodes = [];
        let nodearr = this.Global.getNodeArrPos;
        let that = this;

        this.el = [];
        for (let i = 0; i < nodearr.length; i++) {
            const element = nodearr[i];
            let initarrpos = element.getComponent(pushBoxTs).initarrpos;

            foreachnewarr();
            function foreachnewarr() {

                that.newarr.forEach(e => {
                    //计算欧几里得距离
                    let distancex = Math.abs(element.position.x - e.position.x);
                    let distancey = Math.abs(element.position.y - e.position.y);
                    function fun() {
                        let obj = { element, e }
                        that.el.push(obj);

                        if (that.el.length == 0) {
                            foreachnewarr();
                        }
                    }
                    if (that.Global.moveDirection == 'x' && initarrpos.y == e.y) {
                        if (distancex < 30) {
                            fun()
                        }
                    } else if (that.Global.moveDirection == 'y' && initarrpos.x == e.x) {
                        if (distancey < 30) {
                            fun()
                        }
                    } else if (that.Global.moveDirection == null && (initarrpos.y == e.y || initarrpos.x == e.x)) {
                        if (distancex < 30 && distancey < 30) {
                            fun()
                        }
                    }

                });
            }

            //如果推动的元素靠近二维数组的位置 那就替换他
            let ini;
            const directions = ['down', 'up', 'left', 'right'];
            const closestPairs = { up: null, down: null, left: null, right: null };

            let a;
            directions.forEach(direction => {
                a = 1;
                inis(direction);
            });


            function inis(event) {
                if (that.el.length > 0) {


                    const directionMap = {
                        up: [that.el[i].e.x, that.el[i].e.y + a],
                        down: [that.el[i].e.x, that.el[i].e.y - a],
                        left: [that.el[i].e.x - a, that.el[i].e.y],
                        right: [that.el[i].e.x + a, that.el[i].e.y]
                    };

                    //获取目标元素的相邻元素
                    if (directionMap[event][1] < 0 && event == 'down') {
                        return directionMap.down == null;
                    } else if (directionMap[event][1] > 9 && event == 'up') {
                        return directionMap.up == null;
                    } else if (directionMap[event][0] < 0 && event == 'left') {
                        return directionMap.left == null;
                    } else if (directionMap[event][0] > 9 && event == 'right') {
                        return directionMap.right == null;
                    }

                    ini = that.initarr[directionMap[event][0]][directionMap[event][1]];

                    if (nodearr.some((n: Node) => n == ini.node) || (that.Direction == `${event}` && element !== nodearr[nodearr.length - 1])) {
                        directionMap[event] == null;
                        return;
                    }

                    if (!ini.node || !ini.node.name || ini.node.name === '') {
                        a++;
                        return inis(event);
                    } else {
                        let ininode = ini.node;

                        if (element == ininode) {
                            a++;
                            return inis(event);
                        } else {
                            closestPairs[event] = { element, ininode };
                        }
                    }
                };

            }
            // 输出每个元素在四个方向上的最近节点
            ['left', 'right', 'up', 'down'].forEach(direction => {
                let close = closestPairs[direction];
                if (close) {
                    let childStringElement = close.element.getComponent(Sprite).spriteFrame.name;
                    let childStringIninode = close.ininode.getComponent(Sprite).spriteFrame.name;
                    
                    if (childStringIninode == childStringElement) {
                        bool = true;
                        clearNodes.push(close.element, close.ininode)
                        if (this.node.children.length <= 4) {
                            this.gameOver();
                        }
                    }


                }
            });



        }

        if (bool) {
            //更新不需要的位置为空
            this.el.forEach(index => {
                this.updateArrNode(index.element)
            });

            //更新空的二维数组的对象中的属性
            this.el.forEach(index => {
                let pushboxTs = index.element.getComponent(pushBoxTs);
                this.updateENode(index, pushboxTs)

            });

        }

        clearNodes.forEach(element => {
            element.destroy();
            this.updateArrNode(element)
        });
        clearNodes = [];
        this.el = [];
        this.newarr = [];

    }
    updateENode(element, getTs) {

        element.e.node = element.element;
        element.e.texture = element.element.getComponent(Sprite).spriteFrame.name;

        getTs.InitPos = new Vec3(element.e.position.x, element.e.position.y, element.e.position.z);
        getTs.initarrpos.x = element.e.x;
        getTs.initarrpos.y = element.e.y;
    }

    updateArrNode(element) {
        let ts = element.getComponent(pushBoxTs);
        this.initarr[ts.initarrpos.x][ts.initarrpos.y].node = null;
        this.initarr[ts.initarrpos.x][ts.initarrpos.y].texture = '';

    }
    gameOver() {
        setTimeout(() => {
            if (this.node.children.length === 0 || !this.node.children.length) {
                this.stop.active = true;
            }
        }, 100);
    }
}


